#include "stdafx.h"

#include "./protocol_mgr.h"
#include "./fore_rtdb.h"
#include "./threadLock.h"
#include "./commFun.h"

#ifndef WIN32
	#include <pthread.h>
#endif

long OnTimerThread( TProtocolMgr *pProtocol )
{
	if( pProtocol == NULL ) return -1;
	
	try
	{
		static int s_Idx = 0;
 
	base::my_printf( "OnTimerThread .... \n" );

#ifndef WIN32
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);  
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);  
#endif	 
 
		while( 1 )
		{
			base::MySleep( 1000 );
  
#ifndef WIN32
			pthread_testcancel();
#endif	
			if( s_Idx++ % 5 == 3 )
			{
				pProtocol->scan_online_thread();
			}
		}
	}
	catch( ... )
	{
	}

	return 1;
}


TProtocolMgr::TProtocolMgr()
{
	 
#ifdef WIN32
	m_hTimerThread	= NULL;
#endif
}

TProtocolMgr::~TProtocolMgr()
{
	Destroy();
}

void TProtocolMgr::Destroy()
{
	kill_all_thread();
}

 
void TProtocolMgr::set_thread_name( LPTCPSER_THREADROUTINE threadname )
{
	m_ProcessFunName = threadname;
}

void TProtocolMgr::get_thread_name( LPTCPSER_THREADROUTINE &funName )
{
	funName = m_ProcessFunName;
}

bool TProtocolMgr::Create(  LPTCPSER_THREADROUTINE threadname )
{
 
	set_thread_name( threadname );

	create_all_thread();
	
	return true;
}

void TProtocolMgr::create_all_thread()
{ 
	 
	base::my_printf("loop : create_thread \n" );
	create_single_thread(  );
 
	m_TimerThreadID = XCreateThread( (LPTHREAD_START_ROUTINE)OnTimerThread, this);

	if( m_TimerThreadID <=0 )
	{
		base::my_printf(" error in create OnTimerThread \n");
		return;
	} 
}



void TProtocolMgr::set_thread_status(  bool flag )
{ 
	CAutoLockHelp  lockHelp(&m_thread_status_lock);

	try
	{
		CommThread::COMM_THREAD_ITEM &thread = m_ThreadInfo.Thread ;

		if( flag )
		{
			thread.CurStatus = CommThread::THREAD_STATE_ON;
			base::my_printf(" thread.CurStatus : CommThread::THREAD_STATE_ON; \n" );
		}
		else
		{
			thread.CurStatus = CommThread::THREAD_STATE_OFF;
			base::my_printf(" thread.CurStatus : CommThread::THREAD_STATE_OFF; \n" );
		}
	}
	catch( ... )
	{
	}
	 
}


void TProtocolMgr::scan_online_thread()
{
	CAutoLockHelp  lockHelp(&m_thread_status_lock);

	try
	{ 
		m_ThreadInfo.ResetStatus(); 
		  
		CommThread::COMM_THREAD_ITEM &thread = m_ThreadInfo.Thread ;
 
		if( thread.OldStatus == CommThread::THREAD_STATE_OFF )
		{
			thread.CurStatus = CommThread::THREAD_STATE_ON;
			create_single_thread(  );

			base::MySleep( 500 ); 
		}
		else
		{
			thread.CurStatus = CommThread::THREAD_STATE_ON;
		}
		 
	}
	catch( ... )
	{
	}
	 
}


void TProtocolMgr::create_single_thread( )
{  
	base::my_printf("   create_single_thread \n");
	pthread_t handle = XCreateThread( (LPTHREAD_START_ROUTINE)m_ProcessFunName,  NULL);

	if( handle <= 0 )
	{
		base::my_printf(" error in create thread fun :m_ProcessFunName \n");
		return;
	}
	else{
		base::my_printf(" printf  create_single_thread ok \n");
	}

	m_ThreadInfo.Thread.Handle = handle; 
}


void TProtocolMgr::check_link_info( )
{ 
}


void TProtocolMgr::kill_all_thread()
{
	CAutoLockHelp  lockHelp(&m_thread_status_lock);

	try
	{
		unsigned int exit_code = 0;

 
		if( m_TimerThreadID > 0 ) 
		{
			base::my_printf(" kill scan thread \n");

			pthread_cancel(m_TimerThreadID); 
		} 
		 
		CommThread::COMM_THREAD_ITEM &thread = m_ThreadInfo.Thread ;

		if( thread.CurStatus != CommThread::THREAD_STATE_OFF )
		{
 
			if( thread.Handle > 0 )
			{
				//liunx��pthread_cance ��������һ����ֹ�߳�(����߳���û��ȡ����)�� 
				//����߳����õ�����pthread_cance��pthread_kill��������������Ӧ��ע
				//pthread_killʱ������߳�û�в�׽SIGQUIT�ź�ʱ���̻߳Ὣ���ź��ϴ��������У������������˳�
				//���ֹر��̷߳�ʽ������ȱ��

				base::my_printf(" kill data  process thread \n");

				pthread_cancel(thread.Handle); 
				//int kill_rc = pthread_kill(thread.Handle, 0);!= ESRCH)  //�ź���0�Ǳ����ź� �������������߳��Ƿ����
				//if( kill_rc == ESRCH ) {
				//	base::my_printf("the specified thread did not exists or already quit\n");  
				//}
				//else if( kill_rc == EINVAL ) {
				//	base::my_printf("signal is invalid\n"); 
				//}
				//else { 
				//	pthread_kill(thread.Handle, SIGQUIT);  
				//} 

				thread.Handle = 0;
			}

			usleep( 1000 * 100 ); 
			
			thread.CurStatus = CommThread::THREAD_STATE_OFF/*THREAD_STATE_ON*/;
		 
		}
	}
	catch( ... )
	{
	}
	 
}
